-
Notifications
You must be signed in to change notification settings - Fork 34
Conversation
Все хорошо, но не хватает идентификации ввода сообщения (не обязательно) |
Так, закрывал PR и нашел ошибку:
UPD: И в блокирующих, и в неблокирующих |
А при каких условиях возникает эта ошибка? У меня выход из клиента обрабатывается корректно на сервере. Я, однако, обнаружил, что у клиента при выходе иногда возникало NullPointerException, и на всякий случай это поправил. |
Сейчас не воспроизвелось. Но появилось следующее: При запуске клиента и вводе ника - все ок. Дропаем клиент (Ctrl+C), запускаем новый. Пытаемся ввести ранее использованное имя и получаем ошибку "Это имя занято. Введите другое имя" Client 1: 2020H2 on lab1 [?]
➜ java -jar bclient.jar 127.0.0.1 1843
Введите имя: kek
Привет, kek! Соединение установлено
^C%
2020H2 on lab1 [?] took 4s
➜ java -jar bclient.jar 127.0.0.1 1843
Введите имя: kek
Это имя занято. Введите другое имя: kek
Это имя занято. Введите другое имя: lol
Это имя занято. Введите другое имя: Client 2: ➜ java -jar bclient.jar 127.0.0.1 1843
Введите имя: lol
Привет, lol! Соединение установлено
^C% Server: ➜ java -jar bserver.jar 127.0.0.1 1843
Сервер запущен
<19:37:01> kek присоединился к чату
Exception in thread "Thread-0" java.io.EOFException
at java.base/java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:3211)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1658)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:517)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:475)
at blocking.Server$ServerConnection.run(Server.kt:53)
<19:37:21> lol присоединился к чату
Exception in thread "Thread-2" java.io.EOFException
at java.base/java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:3211)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1658)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:517)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:475)
at blocking.Server$ServerConnection.run(Server.kt:53) Так же момент с вылетом клиента: Подключение клиента - отправка сообщений - остановка клиента - подключение клиента с новым ником: Client: ➜ java -jar bclient.jar 127.0.0.1 1843
Введите имя: lol
Привет, lol! Соединение установлено
hey
<19:41:40> [lol] hey
yo
<19:41:41> [lol] yo
<19:41:43> [kek] q
^C%
2020H2 on lab1 [?] took 14s
➜ java -jar bclient.jar 127.0.0.1 1843
Введите имя: ды
Привет, ды! Соединение установлено
оылвоы
Exception in thread "Thread-0" java.io.EOFException
at java.base/java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:3211)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1658)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:517)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:475)
at blocking.Client$readThread$1.run(Client.kt:81)
at java.base/java.lang.Thread.run(Thread.java:832)
двлл
влдрыкш
Exception in thread "Thread-1" java.net.SocketException: Socket closed
at java.base/sun.nio.ch.NioSocketImpl.ensureOpenAndConnected(NioSocketImpl.java:165)
at java.base/sun.nio.ch.NioSocketImpl.beginWrite(NioSocketImpl.java:366)
at java.base/sun.nio.ch.NioSocketImpl.implWrite(NioSocketImpl.java:411)
at java.base/sun.nio.ch.NioSocketImpl.write(NioSocketImpl.java:440)
at java.base/sun.nio.ch.NioSocketImpl$2.write(NioSocketImpl.java:826)
at java.base/java.net.Socket$SocketOutputStream.write(Socket.java:1052)
at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.drain(ObjectOutputStream.java:1893)
at java.base/java.io.ObjectOutputStream$BlockDataOutputStream.flush(ObjectOutputStream.java:1838)
at java.base/java.io.ObjectOutputStream.flush(ObjectOutputStream.java:726)
at java.base/java.io.ObjectOutputStream.close(ObjectOutputStream.java:747)
at blocking.Client.shutdown(Client.kt:71)
at blocking.Client.access$shutdown(Client.kt:11)
at blocking.Client$writeThread$1.run(Client.kt:101)
at java.base/java.lang.Thread.run(Thread.java:832)
2020H2 on lab1 [?]
➜ java -jar bclient.jar 127.0.0.1 1843
Введите имя: kek
Это имя занято. Введите другое имя: ksldjs
Соединение разорвано
2020H2 on lab1 [?] took 3s
➜ java -jar bclient.jar 127.0.0.1 1843
Введите имя: ghfj
Соединение разорвано Server: ➜ java -jar bserver.jar 127.0.0.1 1843
Сервер запущен
<19:41:35> kek присоединился к чату
<19:41:38> lol присоединился к чату
<19:41:40> [lol] hey
<19:41:41> [lol] yo
<19:41:43> [kek] q
Exception in thread "Thread-0" java.io.EOFException
at java.base/java.io.ObjectInputStream$BlockDataInputStream.peekByte(ObjectInputStream.java:3211)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1658)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:517)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:475)
at blocking.Server$ServerConnection.run(Server.kt:53)
<19:42:28> ды присоединился к чату
<19:42:29> [ды] оылвоы
<19:43:06> ksldjs присоединился к чату
<19:43:11> ghfj присоединился к чату В случае неблокирующих - косяк с разрывом присутствует: Client: 2020H2 on lab1 [?]
➜ java -jar nbclient.jar 127.0.0.1 1843
Введите имя: ke
Привет, ke! Соединение установлено
^C% Server: 2020H2 on lab1 [?] took 5m 2s
➜ java -jar nbserver.jar 127.0.0.1 1843
Сервер запущен
<19:46:41> ke присоединился к чату
Exception in thread "main" java.io.StreamCorruptedException: invalid stream header: 00000000
at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:964)
at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:403)
at non_blocking.SocketChannelUtilsKt.readMessage(SocketChannelUtils.kt:28)
at non_blocking.Server.readAndSendResponse(Server.kt:53)
at non_blocking.Server.<init>(Server.kt:41)
at non_blocking.Server$Companion.main(Server.kt:96)
at non_blocking.Server.main(Server.kt) |
Поправил, сейчас все должно работать нормально. |
Принято |
Лабораторная работа № 1
Работа выполнена на языке Kotlin (версия Kotlin 1.4.20, версия Java 15.0.1). Сборка производится с помощью Gradle (версия 6.5.1)
Описание
При создании клиента необходимо ввести имя. Оно должно быть уникальным и не содержать символов
[
и]
. Чтобы завершить работу, необходимо ввести!q
. Помимо обычных сообщений передаются также служебные уведомления о подключении или отключении пользователей.Использование
Названия jar-файлов (здесь и в дальнейшем без расширения):
bserver
bclient
nbserver
nbclient
Сборка
Сборка всех jar-файлов:
Сборка конкретного файла:
Запуск
Протокол
Каждое сообщение наследует класс
Message
. Возможные типы сообщений:ConnectionRequest
username
ConnectionResponse
username
,date
ConnectionDenied
username
DisconnectionRequest
username
DisconnectionResponse
username
,date
UserMessage
username
,message
,date
Поля:
username
: ник пользователяdate
: время прихода сообщения на серверmessage
: сообщение